<?php
/**
 * 
 *
 * @package api
 * @subpackage collections
 * @author $Author$
 * @version $Id: AbstractQueue.php 14 2006-11-28 22:05:19Z rdff3 $
 */
/** 
 *
 */
require_once( "util/Queue.php" );
require_once( "lang/Object.php" );
require_once( "util/AbstractCollection.php" );

/**
 * Abstract class AbstractQueue
 *
 * This class provides skeletal implementations of some Queue  operations. The implementations in this class are 
 * appropriate when the base implementation does not allow null  elements. Methods add, remove, and element are based 
 * on offer, poll, and peek, respectively but throw exceptions instead of indicating failure via false or null returns.
 * 
 * A Queue implementation that extends this class must minimally define a method Queue.offer(E) which does not permit 
 * insertion of null elements, along with methods Queue.peek(), Queue.poll(), Collection.size(), and a Collection.iterator() 
 * supporting CollectionIterator.remove(). Typically, additional methods will be overridden as well. If these requirements cannot be 
 * met, consider instead subclassing AbstractCollection.
 * 
 * This class is a member of the PHP Collections Framework. 
 *
 * @package api
 * @subpackage collections
 * @author $Author$
 * @version $Id: AbstractQueue.php 14 2006-11-28 22:05:19Z rdff3 $
 */
abstract class AbstractQueue extends AbstractCollection implements Queue {

	public function __construct() {
		parent::__construct();
	}

	/**
	 * Adds the specified element to this queue.
	 *
	 * This implementation returns true if offer succeeds, else throws an IllegalStateException.
	 *
	 * @param Object $o the element
	 * @returns boolean true (as per the general contract of Collection.add)
	 * @throws {@link NullPointerException} - if the specified element is null 
	 * @throws {@link IllegalStateException} - if element cannot be added
	 */
	public function add( Object $o ) {
		if (is_null($o))
			throw new NullPointerException();
	
		if ($this->offer( $o ) )
			return true;
		else
			throw new IllegalStateException();
	}
	
	/**
	 * Adds all of the elements in the specified collection to this queue. 
	 *
	 * Attempts to addAll of a queue to itself result in IllegalArgumentException. Further, the behavior of this 
	 * operation is undefined if the specified collection is modified while the operation is in progress.
	 * 
	 * This implementation iterates over the specified collection, and adds each element returned by the iterator 
	 * to this collection, in turn. A runtime exception encountered while trying to add an element (including, in 
	 * particular, a null element) may result in only some of the elements having been successfully added when the 
	 * associated exception is thrown. 
	 *
	 * @param Collection $c collection whose elements are to be added to this collection.
	 * @returns boolean true if this collection changed as a result of the call.
	 * @throws {@link NullPointerException} - if the specified collection or any of its elements are null.
	 * @throws {@link IllegalArgumentException} - if $c is this queue.
	 */
	public function addAll( Collection $c ) {
		if ($c->equals( $this ))
			throw new IllegalArgumentException();
		
		$return_value = false;
		$iterator = $c->iterator();
		while( $iterator->hasNext() ) {
			$return_value = $return_value || $this->add( $iterator->getNext() );
		}
		return $return_value;
	}
	
	/**
	 * Removes all of the elements from this collection.
	 *
	 * Removes all of the elements from this collection. The collection will be empty after this call returns. This implementation
	 * repeatedly invokes poll until it returns null. 
	 */
	public function clear() {
		while ($this->poll() != null);
	}
	
	/**
	 * Retrieves, but does not remove, the head of this queue.
	 *
	 * This implementation returns the result of peek unless the queue is empty.
	 *
	 * @returns Object the head of this queue
	 * @throws {@link NoSuchElementException} - if this queue is empty.
	 */
	public function element() {
		if ($this->isEmpty())
			throw new NoSuchElementException();
			
		return $this->peek();
	}
	
	/**
	 * Retrieves and removes the head of this queue.
	 *
	 * This implementation returns the result of poll unless the queue is empty.
	 *
	 * @returns Object the head of this queue
	 * @throws {@link NoSuchElementException} - if this queue is empty.
	 */
	public function removeHead() {
		if ($this->isEmpty())
			throw new NoSuchElementException();
			
		return $this->poll();
	}


}

?>